package com.ikingtech.framework.sdk.web.configuration;

import com.ikingtech.framework.sdk.utils.Tools;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.parameters.HeaderParameter;
import io.swagger.v3.oas.models.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
import org.springdoc.core.customizers.GlobalOperationCustomizer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import java.util.Comparator;
import java.util.stream.Collectors;

/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
public class OpenApiConfiguration {

    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${iking.framework.web.version}")
    private String version;

    @Bean
    public GlobalOpenApiCustomizer orderGlobalOpenApiCustomizer() {
        return openApi -> {
            Paths sortedPath = new Paths();
            openApi.getPaths().entrySet().stream()
                    .filter(entry ->
                            null != entry.getValue() &&
                                    Tools.Coll.isNotBlank(entry.getValue().readOperations()) &&
                                    Tools.Str.isNotBlank(entry.getValue().readOperations().get(0).getSummary()))
                    .sorted(Comparator.comparing(entry -> entry.getValue().readOperations().get(0).getSummary()))
                    .forEach(entry -> sortedPath.put(entry.getKey(), entry.getValue()));

            openApi.setPaths(sortedPath);
            openApi.setTags(openApi.getTags().stream().sorted(Comparator.comparing(Tag::getName)).collect(Collectors.toList()));
        };
    }

    @Bean
    public GlobalOperationCustomizer operationCustomize() {
        return (operation, handlerMethod) -> {
            operation.addParametersItem(
                    new HeaderParameter().name("Authorization").example("Bearer iking").description("身份认证Token").required(true)
            );
            operation.addParametersItem(
                    new HeaderParameter().name("menu-id").example("").description("菜单编号").required(false)
            );
            operation.addParametersItem(
                    new HeaderParameter().name("X-Tenant").example("").description("租户标识").required(false)
            );
            operation.addParametersItem(
                    new HeaderParameter().name("X-Domain").example("").description("域标识").required(false)
            );
            operation.addParametersItem(
                    new HeaderParameter().name("X-App").example("").description("应用标识").required(false)
            );
            return operation;
        };
    }

    @Bean
    public OpenAPI customOpenApi() {
        return new OpenAPI()
                .info(new Info()
                        .title(this.applicationName + " 接口文档")
                        .version(this.version)
                );
    }
}
